#include "SalesmanChromosome.h"
#include "parameters.h"

//TODO should not be used
SalesmanChromosome::SalesmanChromosome() : IntegerChromosome()
{
    TRACE_FUNC
}

SalesmanChromosome::SalesmanChromosome(int _min, int _max) : IntegerChromosome(_min, _max)
{
    TRACE_FUNC
}

SalesmanChromosome::SalesmanChromosome(int size) : IntegerChromosome(size, 0, size-1)
{
    TRACE_FUNC
}

SalesmanChromosome::SalesmanChromosome(const SalesmanChromosome &other) : IntegerChromosome(other)
{
    TRACE_FUNC
}

SalesmanChromosome::~SalesmanChromosome()
{
    TRACE_FUNC
}

void SalesmanChromosome::setData(QList<int> _numberList)
{
    geneArray.clear();

    for(int i=0;i<_numberList.size();++i)
        geneArray.append(_numberList.at(i));
}

void SalesmanChromosome::setRandom()
{
    TRACE_FUNC_ENTRY
    QList<int> indexes;

    for(int i=0;i<geneArray.size();++i)
        indexes.append(i);

    for(int i=0;i<geneArray.size();++i)
    {
        int index = qrand() % indexes.size();
        geneArray.replace(i, indexes[index]);
        indexes.removeAt(index);
    }
    TRACE_FUNC_EXIT
}

void SalesmanChromosome::crossOver(const Chromosome& partner)
{
    TRACE_FUNC_ENTRY
    //qDebug() << "SalesmanChromosome::crossOver";
    if(this->size() != partner.size())
        qFatal("Parents chromosomes lenght is different!");

    int crossOverPosition;
    //cross point randomed, greater than 0, smaller than chromosome size
    crossOverPosition = (qrand() % (geneArray.size() -1)) + 1;
    //qDebug() << "mother: " << *this;
    //qDebug() << "father: " << partner;
    //qDebug() << "crossOverPosition: " << crossOverPosition;

    for(int i=crossOverPosition;i<geneArray.size();++i)
    {
        geneArray.swap(i, geneArray.indexOf(partner.at(i).toInt()));
        geneArray.replace(i, partner.at(i).toInt());
    }

    this->setFitness(0);

    //qDebug() << "child:  " << *this;

    TRACE_FUNC_EXIT
}

void SalesmanChromosome::mutate(int index)
{
    TRACE_FUNC_ENTRY
   // int swapPosition1 = getRandomIntegerValue();
    int swapPosition2 = rand() % size();

    //random unique swap positions
    while(index == swapPosition2)
        swapPosition2 = rand() % size();

    //qDebug() << "swapPosition1: " << index;
    //qDebug() << "swapPosition2: " << swapPosition2;
    //qDebug() << "before mutation: " << *this;
    geneArray.swap(index, swapPosition2);
    //qDebug() << "after  mutation: " << *this;
    TRACE_FUNC_EXIT
}

Chromosome* SalesmanChromosome::duplicate() const
{
    TRACE_FUNC
    return new SalesmanChromosome(*this);
}
